package com.css.bjdt_core.executive.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nutz.dao.Dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.css.bjdt_core.cell.entity.Cell;
import com.css.bjdt_core.cell.entity.Cell.CellType;
import com.css.bjdt_core.cell.entity.CellData;
import com.css.bjdt_core.cell.service.CellDataService;
import com.css.bjdt_core.cell.service.CellService;
import com.css.bjdt_core.dataSetManage.entity.ViewDataItem;
import com.css.bjdt_core.dataSetManage.service.DataItemService;
import com.css.bjdt_core.executive.Executor;
import com.css.bjdt_core.executive.entity.Exp;
import com.css.bjdt_core.executive.factory.ExecutorFactory;
import com.css.bjdt_core.executive.report.ReportCache;
import com.css.bjdt_core.executive.report.ReportCache;
import com.css.bjdt_core.executive.report.ReportRequest;
import com.css.bjdt_core.executive.util.CalcExpParser;
import com.css.bjdt_core.executive.util.ExpParser;
import com.css.bjdt_core.executive.util.SqlExpProducer;
import com.css.bjdt_core.report.entity.RptTemplateUnitRela;
import com.css.bjdt_core.report.entity.ViewRptStatCategory;
import com.css.bjdt_core.report.entity.ViewRptTemplateCondition;
import com.css.bjdt_core.report.service.ReportCalcService;
import com.css.bjdt_core.report.service.ReportConditionService;
import com.css.bjdt_core.report.service.ReportStatCategoryService;
import com.css.bjdt_core.report.service.ReportTemplateManageService;
import com.css.bjdt_core.report.service.ReportTemplateUnitRelaService;
import com.css.bjdt_core.reportFill.entity.CellDataValue;
import com.css.bjdt_core.reportFill.service.ReportFillService;
import com.css.bjdt_core.reportPrepare.entity.ViewRptGroupTemplate;
import com.css.bjdt_core.summary.service.ReportSummaryNewService;
import com.css.bjdt_core.util.CommonUtil;
import com.css.bjdt_core.util.ExecutorPool;
import com.css.bjdt_core.util.ReportConstant;

@Service
public class ReportExecuteService {
	@Autowired
	private ReportTemplateManageService reportTemplateService;
	@Autowired
	private ReportTemplateUnitRelaService reportTemplateUnitRelaService;
	@Autowired
	private ReportStatCategoryService reportStatCategoryService;
	@Autowired
	private ReportConditionService reportConditionService;
	@Autowired
	private ReportCalcService reportCalcService;
	@Autowired
	private DataItemService dataItemService;
	@Autowired
	private CellService cellService;
	@Autowired
	private CellDataService cellDataService;
	@Autowired
	private ReportSummaryNewService reportSummaryNewService;

	private SqlExpProducer producer = SqlExpProducer.getInstance();
	private ExpParser parser = CalcExpParser.getInstance();

	private static Log logger = LogFactory.getLog(ReportExecuteService.class);

	private static ExecutorService pool = ExecutorPool.getInstance().getPool();

	private ReportCache cache = ReportCache.getInstance();

	@Autowired
	private ReportFillService reportFillService;

	@Autowired
	private Dao dao;

	static ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");

	/**
	 * 初始化报表
	 * 
	 * @param annualId 年度id
	 * @return 初始化失败的报表id集合
	 */
	public List<String> initReport(String annualId) {
		List<ViewRptGroupTemplate> templates = reportTemplateService.getRptTemplateByAnnualId(annualId);
		return initReport(templates);
	}

	/**
	 * 初始化报表
	 * 
	 * @param templateIds 报表id
	 * @return 初始化失败的报表id
	 */
	public List<String> initReport(String... templateIds) {
		List<ViewRptGroupTemplate> templates = reportTemplateService.getRptTemplateByIds(templateIds);
		return initReport(templates);
	}

	/**
	 * 初始化报表
	 * 
	 * @param templates
	 * @return
	 */
	private List<String> initReport(List<ViewRptGroupTemplate> templates) {
		Map<String, ViewDataItem> itemMap = dataItemService.getPKAndFK();
		producer.setItemMap(itemMap);
		List<Cell> updateCells = new ArrayList<Cell>();
		List<String> errorTemplateIds = new ArrayList<String>();
		for (ViewRptGroupTemplate template : templates) {
			try {
				List<Cell> statCells = initStatIndicator(template.getTemplateId());
				if (statCells != null && statCells.size() > 0) {
					updateCells.addAll(statCells);
				}
				List<Cell> calcCells = initCalcIndicator(template.getTemplateId());
				if (calcCells != null && calcCells.size() > 0) {
					updateCells.addAll(calcCells);
				}
				List<Cell> quoteCells = initQuoteIndicator(template.getTemplateId());
				if (quoteCells != null && quoteCells.size() > 0) {
					updateCells.addAll(quoteCells);
				}
			} catch (Exception e) {
				errorTemplateIds.add(template.getTemplateId());
				logger.error("init Report occur error ! Template ID = " + template.getTemplateId(), e);
			}
		}
		try {
			persistReport(updateCells);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return errorTemplateIds;
	}

	/**
	 * 生成报表数据
	 * 
	 * @param request 报表请求
	 */
	public void generateReportData(HttpSession session, ReportRequest request) {
		generateIndicatorData(session, request);
	}

	private List<Cell> getExetuableCellList(String templateId) {
		List<Cell> src = new ArrayList<Cell>();
		List<Cell> temps = cellService.getCellStrategyByTemplateId(templateId);
		for (Cell cell : temps) {
			String strategyId = cell.getStrategyId();
			String strategyClassName = cell.getStrategyClassName();
			if (strategyClassName != null && !strategyId.equals("2") && null != cell.getCellLevel()) {
				Executor executor = ExecutorFactory.create(strategyClassName);
				if (executor != null) {
					executor.init(cell);
					src.add(cell);
				} else {
					logger.debug("cell id = " + cell.getCellId() + " do not have executor !");
				}
			}
		}
		return src;
	}

	/**
	 * 生成指标数据
	 * 
	 * @param request
	 */
	private void generateIndicatorData(HttpSession session, ReportRequest request) {
		cellDataService.createTable(request.getAnnualId());

		List<CellData> cellDataList = execute(session, request);
		//executors.shutdownAndAwaitTermination();
		//每个单元格的公式计算
		if (request.getIsAllGenerateIndicatorData().equals("1")) {
			executeCellFormulaCalculation(cellDataList, request.getTemplateIds(), request.getReportDzzId(),
					request.getAnnualId());
		}
	}

	/**
	 * 初始化统计类型指标
	 * 
	 * @param templateId
	 * @return
	 */
	private List<Cell> initStatIndicator(String templateId) {
		Map<String, List<ViewRptTemplateCondition>> conditionMap = reportConditionService
				.buildConditionMapByTemplateId(templateId);
		producer.setConditionMap(conditionMap);
		List<Cell> statCells = cellService.getRawCellsByTemplateIdAndType(templateId, CellType.stat);
		List<ViewRptStatCategory> statCategorys = reportStatCategoryService.getStatCategoryByTemplateId(templateId);
		fillCellStatCategory(statCells, statCategorys);
		for (Cell statCell : statCells) {
			producer.produceSqlExp(statCell);
			statCell.setCellLevel(ReportRequest.MAX_VALUE);
		}
		return statCells;
	}

	/**
	 * 初始化计算类型指标
	 * 
	 * @param templateId
	 * @return
	 */
	private List<Cell> initCalcIndicator(String templateId) {
		Map<String, List<Exp>> calcMap = reportCalcService.buildReportCalcMapByTemplateId(templateId);
		parser.setExpMap(calcMap);
		List<Cell> calcCells = cellService.getRawCellsByTemplateIdAndType(templateId, CellType.calc);
		for (Cell calcCell : calcCells) {
			parser.parseExp(calcCell);
		}
		return calcCells;
	}

	/**
	 * 初始化引用类型指标
	 * 
	 * @param templateId
	 * @return
	 */
	private List<Cell> initQuoteIndicator(String templateId) {
		List<Cell> quoteCells = cellService.getRawCellsByTemplateIdAndType(templateId, CellType.quote);
		for (Cell quoteCell : quoteCells) {
			quoteCell.setCellLevel(ReportRequest.MAX_VALUE);
		}
		return quoteCells;
	}

	/**
	 * 根据绝对起始行和绝对终止行与绝对起始列和绝对终止列,为每个指标设置统计类别
	 * 注：如果区域和指标存在关系,就没那么麻烦
	 * 
	 * @param statCells
	 * @param statCategorys
	 */
	private void fillCellStatCategory(List<Cell> statCells, List<ViewRptStatCategory> statCategorys) {
		if (statCells == null || statCategorys == null || statCells.size() == 0 || statCategorys.size() == 0) {
			return;
		}
		for (ViewRptStatCategory statCategory : statCategorys) {
			int startRowNum = Integer.parseInt(statCategory.getAbsStartRow());
			int endRowNum = Integer.parseInt(statCategory.getAbsEndRow());
			int startColNum = Integer.parseInt(statCategory.getAbsStartCol());
			int endColNum = Integer.parseInt(statCategory.getAbsEndCol());
			List<Integer> rowlist = new ArrayList<Integer>();
			List<Integer> collist = new ArrayList<Integer>();
			for (int i = startRowNum; i <= endRowNum; i++) {
				rowlist.add(i);
			}
			for (int j = startColNum; j <= endColNum; j++) {
				collist.add(j);
			}
			Integer[] rowRange = rowlist.toArray(new Integer[0]);
			Integer[] colRange = collist.toArray(new Integer[0]);
			for (Cell statCell : statCells) {
				if (ArrayUtils.contains(rowRange, statCell.getAbsRowNum())
						&& ArrayUtils.contains(colRange, statCell.getAbsColNum())) {
					statCell.setStatCategory(statCategory);
				}
			}
		}
	}

	private void persistReport(List<Cell> updateCells) {
		cellService.update(updateCells);
		producer.destory();
		parser.destory();
		updateCells.clear();
		updateCells = null;
	}

	private List<CellData> execute(HttpSession session, ReportRequest request) {

		List<RptTemplateUnitRela> templateUnitRelas = reportTemplateUnitRelaService.getTemplateUnitRela(request);
		List<Callable<List<CellData>>> tasks = new ArrayList<Callable<List<CellData>>>();
		if (templateUnitRelas.size() > 0) {
			String annualId = templateUnitRelas.get(0).getAnnualId();
			Map<String, RptTemplateUnitRela> tuMap = new HashMap<String, RptTemplateUnitRela>();
			List<Cell> cells = new ArrayList<Cell>();
			int genSize = 0;

			List<String> funcListIds = cellDataService.isFuncExist(request.getTemplateIds());
			for (RptTemplateUnitRela templateUnitRela : templateUnitRelas) {
				List<Cell> src = getExetuableCellList(templateUnitRela.getTemplateId());
				genSize += src.size();
				if (funcListIds.contains(templateUnitRela.getTemplateId())) {
					for (Cell cell : src) {
						if (!cell.getStrategyId().equals("1")) {
							cells.add(cell);
						}
					}
					ExecuteFuncThread executeThread = new ExecuteFuncThread(session, src, templateUnitRela);
					tasks.add(executeThread);
				} else {
					cells.addAll(src);
				}
				tuMap.put(templateUnitRela.getTemplateId(), templateUnitRela);
				/*// 按指标取值优先级排序
				Collections.sort(cellList, new Comparator<Cell>() {
					@Override
					public int compare(Cell cell1, Cell cell2) {
						return cell2.getCellLevel() - cell1.getCellLevel();
					}
				});*/
				//List<CellData> list = Collections.synchronizedList(new ArrayList<CellData>());
				// 把手动输入的指标值存储到list中
				/*if (cellDataMap.get(templateUnitRela.getTemplateId()) != null) {
					target.addAll(cellDataMap.get(templateUnitRela.getTemplateId()));
				}*/

				//pool.execute(new ExecuteThread(templateUnitRela));
			}

			session.setAttribute("generationSize", genSize);
			List<List<Cell>> list = CommonUtil.subList(cells, 30);
			for (List<Cell> cellList : list) {
				ExecuteThread executeThread = new ExecuteThread(session, cellList, tuMap);
				tasks.add(executeThread);
			}
			List<Future<List<CellData>>> res = null;
			session.setAttribute("generationCounter", new AtomicInteger(0));
			try {
				logger.debug("------------------------------------->invoke 执行 ReportExecuteService");
				res = pool.invokeAll(tasks);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			List<CellData> cellDataList = new ArrayList<CellData>();
			for (Future<List<CellData>> fu : res) {
				try {
					if (fu.get() != null && fu.get().size() != 0) {
						cellDataList.addAll(fu.get());
					}
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (ExecutionException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			logger.debug("------------------------------------->invoke 执行完成  ReportExecuteService");
			reportSummaryNewService.saveReportValueSummary(cellDataList, annualId);
			//cellDataList = null;
			session.setAttribute("generationCounter", new AtomicInteger(0));
			session.setAttribute("generationSize", 0);
			return cellDataList;
		} else {
			return null;
		}
	}

	private void readyForTemplate(RptTemplateUnitRela templateUnitRela, List<Cell> src, List<CellData> target) {

	}

	// 没有事务有隐患
	private List<CellData> executeByTemplate(List<Cell> src, Map<String, RptTemplateUnitRela> tuMap) {

		// 把list存储到cache中供其他依赖指标使用
		//cache.putCellData(templateUnitRela.getReportUnitId() + templateUnitRela.getTemplateId(), list);
		List<CellData> target = new ArrayList<CellData>();
		for (Cell cell : src) {
			try {
				RptTemplateUnitRela tuR = tuMap.get(cell.getTemplateId());
				String cellValue = cell.getExecutor().execute(cell, tuR);
				CellData cellData = new CellData(cell, cellValue, tuR.getReportUnitId());
				target.add(cellData);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		// 按年度id、党组织id、报表id删除指标数据(只删除统计类型、计算类型、引用类型指标)
		/*cellDataService.deleteCellDataByDzzIdAndTemplateIdGy(templateUnitRela.getAnnualId(),
				templateUnitRela.getReportUnitId(), templateUnitRela.getTemplateId());*/
		// 清除缓存
		//cache.clearCellData(templateUnitRela.getReportUnitId() + templateUnitRela.getTemplateId());
		//cellDataService.batchInsertCellData(templateUnitRela.getAnnualId(), target);
		logger.debug("------------------------------------->一个线程结束了  ReportExecuteService");
		return target;
	}

	private List<CellData> executeFuncByTemplate(List<Cell> src, RptTemplateUnitRela tu) {

		// 把list存储到cache中供其他依赖指标使用
		//cache.putCellData(templateUnitRela.getReportUnitId() + templateUnitRela.getTemplateId(), list);
		List<CellData> target = new ArrayList<CellData>();
		try {
			Map<String, String> res = cellDataService.getCellDataByFunc(tu.getTemplateId(), tu.getReportUnitId(),
					tu.getStartTimeStr(), tu.getEndTimeStr());
			Map<String, Cell> cellMap = new HashMap<String, Cell>();
			for (Cell cell : src) {
				cellMap.put(cell.getCellId(), cell);
			}
			for (Map.Entry<String, String> data : res.entrySet()) {
				Cell cell = cellMap.get(data.getKey());
				if(cell != null) {
					CellData cellData = new CellData(cell, data.getValue(), tu.getReportUnitId());
					target.add(cellData);
				} else {
					logger.error("executeFuncByTemplate invalid cell id: " + data.getKey());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 按年度id、党组织id、报表id删除指标数据(只删除统计类型、计算类型、引用类型指标)
		/*cellDataService.deleteCellDataByDzzIdAndTemplateIdGy(templateUnitRela.getAnnualId(),
				templateUnitRela.getReportUnitId(), templateUnitRela.getTemplateId());*/
		// 清除缓存
		//cache.clearCellData(templateUnitRela.getReportUnitId() + templateUnitRela.getTemplateId());
		//cellDataService.batchInsertCellData(templateUnitRela.getAnnualId(), target);
		logger.debug("------------------------------------->一个线程结束了  ReportExecuteService");
		return target;
	}

	/*public void shutdownAndAwaitTermination() {
		pool.shutdown();
		try {
			pool.awaitTermination(30, TimeUnit.MINUTES);
		} catch (InterruptedException e) {
			logger.error(e);
		} finally {
			pool = null;
		}
	}*/

	class ExecuteThread implements Callable<List<CellData>> {
		private List<Cell> src;
		private HttpSession session;
		Map<String, RptTemplateUnitRela> tuMap;

		public ExecuteThread(HttpSession session, List<Cell> src, Map<String, RptTemplateUnitRela> tuMap) {
			this.src = src;
			this.session = session;
			this.tuMap = tuMap;
		}

		@Override
		public List<CellData> call() {
			long start = System.nanoTime();
			List<CellData> cellDataList = executeByTemplate(src, tuMap);
			long end = System.nanoTime();
			logger.error("ExecuteThread : " + (end - start) / 1000000);
			start = end;
			AtomicInteger counter = (AtomicInteger) session.getAttribute("generationCounter");
			counter.addAndGet(cellDataList.size());
			session = null;
			return cellDataList;
		}
	}

	public void executeCellFormulaCalculation(List<CellData> cellDataList, List<String> templateIds, String dzzId,
			String annualId) {

		//最后保存的计算格的cellDataList
		List<CellData> calcCellDataList = new ArrayList<CellData>();

		//相对坐标(行列计算公式)
		Map<String, Map<String, String>> cellDataRelMap = new HashMap<String, Map<String, String>>();
		//绝对坐标(单元格计算公式)
		Map<String, Map<String, String>> cellDataAbsMap = new HashMap<String, Map<String, String>>();

		//initializing rel & abs map
		for(String templateId : templateIds) {
			cellDataRelMap.put(templateId, new HashMap<String, String>());
			cellDataAbsMap.put(templateId, new HashMap<String, String>());
		}

		for (CellData cellData : cellDataList) {
			Map<String, String> relMap = cellDataRelMap.get(cellData.getTemplateId());
			//相对坐标的
			if (cellData.getRelColNum() != null && !("".equals(cellData.getRelColNum()))) {
				String relKey = cellData.getTemplateId() + "--" + cellData.getRelColNum() + "--"
						+ cellData.getRelRowNum();
				relMap.put(relKey, cellData.getCellValue());
			}

			//绝对坐标
			Map<String, String> absMap = cellDataAbsMap.get(cellData.getTemplateId());
			String absKey = cellData.getTemplateId() + "--" + cellData.getAbsColNum() + "--" + cellData.getAbsRowNum();
			absMap.put(absKey, cellData.getCellValue());
		}

		List<ExecuteCalculationThread> tasks = new ArrayList<ExecuteCalculationThread>();

		for (String templateId : templateIds) {
			ExecuteCalculationThread executeThread = new ExecuteCalculationThread(templateId, annualId, dzzId,
					cellDataAbsMap.get(templateId), cellDataRelMap.get(templateId));
			tasks.add(executeThread);
		}

		List<Future<List<CellData>>> res = null;
		try {
			res = pool.invokeAll(tasks);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		for (Future<List<CellData>> fu : res) {
			try {
				if (fu.get() != null && fu.get().size() != 0) {
					calcCellDataList.addAll(fu.get());
				}
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ExecutionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		reportSummaryNewService.saveReportValueSummary(calcCellDataList, annualId);
	}

	class ExecuteCalculationThread implements Callable<List<CellData>> {
		private String templateId;
		private String annualId;
		private String dzzId;
		private Map<String, String> cellDataAbsMap;
		private Map<String, String> cellDataRelMap;

		public ExecuteCalculationThread(String templateId, String annualId, String dzzId,
				Map<String, String> cellDataAbsMap, Map<String, String> cellDataRelMap) {
			this.templateId = templateId;
			this.annualId = annualId;
			this.dzzId = dzzId;
			this.cellDataAbsMap = cellDataAbsMap;
			this.cellDataRelMap = cellDataRelMap;
		}

		@Override
		public List<CellData> call() {
			List<CellData> calcCellDataListThread = new ArrayList<CellData>();

			List<Cell> cellOtherList = new ArrayList<Cell>();
			//获取所有计算格的指标

			List<Cell> cellList = cellService.getCellStrategyByTemplateId(templateId);
			//绝对坐标MAP（cell）
			Map<String, Cell> cellAbsMap = new HashMap<String, Cell>();
			//相对坐标MAP（cell）
			Map<String, Cell> cellRelMap = new HashMap<String, Cell>();
			//先把该张报表的CELL对象都放到MAP里面去，方便后面进行转换
			for (Cell cell : cellList) {
				String absMapKey = cell.getAbsColNum() + "--" + cell.getAbsRowNum();
				cellAbsMap.put(absMapKey, cell);
				if (cell.getRelColNum() != null && cell.getRelRowNum() != null) {
					String relMapKey = cell.getRelColNum() + "--" + cell.getRelRowNum();
					cellRelMap.put(relMapKey, cell);
				}
			}

			List<CellDataValue> cellDataValueHandList = reportFillService.getAllCellDataValueByType(templateId,
					annualId, dzzId, "2");
			for (CellDataValue cellDataValue : cellDataValueHandList) {
				String key = templateId + "--" + cellDataValue.getAbsColNum() + "--" + cellDataValue.getAbsRowNum();
				cellDataAbsMap.put(key, cellDataValue.getCellValue());
			}
			//这里面先解析计算格的计算公式，解析完毕之后，开始根据KEY去自动生成格里面去找数，如果没有数，在去手填的格里面找数，都没有就赋予0值。
			for (Cell cell : cellList) {

				try {
					//判断当前单元格是否是计算格
					if (!cell.getCellType().equals("3")) {
						continue;
					}
					String cellFormual = "";
					try {
						cellFormual = cell.getCalcExp().getCellExp().replaceAll("\\[", "").replaceAll("\\]", "");
					} catch (Exception e) {
						continue;
					}

					String finalCellData = "";
					if (cellFormual.indexOf("cell:") != -1) {
						//单元格计算
						cellFormual = cellFormual.replaceAll("cell:", "");
						String[] coordinateList = cellFormual.split(ReportConstant.OPERATOR_ARITH);
						for (String coordinate : coordinateList) {
							String coordinateNew = coordinate.replaceAll("_", ",");
							String[] numArray = coordinateNew.split(",");
							String numKey = templateId + "--" + numArray[1] + "--" + numArray[0];
							String cellValue = cellDataAbsMap.get(numKey);
							if (cellValue == null) {
								cellValue = "0";
							}
							cellFormual = cellFormual.replace("_", ",").replaceFirst(coordinate.replaceAll("_", ","),
									cellValue);
						}

						try {
							String value = jse.eval(cellFormual).toString();
							BigDecimal valueBd = new BigDecimal(value);
							finalCellData = valueBd.intValue() + "";
						} catch (ScriptException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
							finalCellData = "0";
						}
						String calckey = templateId + "--" + cell.getAbsColNum() + "--" + cell.getAbsRowNum();
						cellDataAbsMap.put(calckey, finalCellData);
						cellOtherList.add(cell);
					} else {
						//行列计算
						String[] coordinateList = cellFormual.split(ReportConstant.OPERATOR_ARITH);
						for (String coordinate : coordinateList) {
							String coordinateNew = coordinate.replaceAll("_", ",");
							String[] numArray = coordinateNew.split(",");
							Cell cellNew = cellRelMap.get(numArray[1] + "--" + numArray[0]);
							String numKey = templateId + "--" + cellNew.getAbsColNum() + "--" + cellNew.getAbsRowNum();
							//转成绝对坐标，从绝对坐标里面取值
							String cellValue = cellDataAbsMap.get(numKey);
							if (cellValue == null) {
								cellValue = "0";
							}
							try {
								cellFormual = cellFormual.replaceFirst(coordinate, cellValue);
							} catch (Exception e) {
								e.printStackTrace();
							}
						}
						try {
							String value = jse.eval(cellFormual).toString();
							BigDecimal valueBd = new BigDecimal(value);
							finalCellData = valueBd.intValue() + "";
						} catch (ScriptException e) {
							// TODO Auto-generated catch block
							finalCellData = "0";
						}
						//将计算格也塞入MAP里面去，因为会有依赖计算在里面
						String calckey = templateId + "--" + cell.getRelColNum() + "--" + cell.getRelRowNum();
						cellDataRelMap.put(calckey, finalCellData);
						String calaAbsKey = templateId + "--" + cell.getAbsColNum() + "--" + cell.getAbsRowNum();
						cellDataAbsMap.put(calaAbsKey, finalCellData);
						cellOtherList.add(cell);
						logger.debug("报表单元格信息:" + "等级" + cell.getCellLevel() + "值：" + cellFormual + "相对坐标:"
								+ CommonUtil.numToLetter(cell.getRelColNum() + "") + cell.getRelRowNum());
					}
				} catch (Exception e) {
					System.out.println(cell.getCellId() + "--------------------错误信息");
					e.printStackTrace();
				}

			}
			//重新算一遍，有先后顺序问题，导致的计算的时候有时候是0就已经算了
			for (Cell cell : cellOtherList) {
				try {
					String cellFormual = "";
					try {
						cellFormual = cell.getCalcExp().getCellExp().replaceAll("\\[", "").replaceAll("\\]", "");
					} catch (Exception e) {
						continue;
					}

					String finalCellData = "";

					if (cellFormual.indexOf("cell:") != -1) {
						//单元格计算
						cellFormual = cellFormual.replaceAll("cell:", "");
						String[] coordinateList = cellFormual.split(ReportConstant.OPERATOR_ARITH);
						for (String coordinate : coordinateList) {
							String coordinateNew = coordinate.replaceAll("_", ",");
							String[] numArray = coordinateNew.split(",");
							String numKey = templateId + "--" + numArray[1] + "--" + numArray[0];
							String cellValue = cellDataAbsMap.get(numKey);
							if (cellValue == null) {
								cellValue = "0";
							}
							cellFormual = cellFormual.replace("_", ",").replaceFirst(coordinate.replaceAll("_", ","),
									cellValue);
						}
						try {
							String value = jse.eval(cellFormual).toString();
							BigDecimal valueBd = new BigDecimal(value);
							finalCellData = valueBd.intValue() + "";
						} catch (ScriptException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
							finalCellData = "0";
						}
						CellData cellData = new CellData(cell, finalCellData, dzzId);
						calcCellDataListThread.add(cellData);
					} else {
						//行列计算
						String[] coordinateList = cellFormual.split(ReportConstant.OPERATOR_ARITH);
						for (String coordinate : coordinateList) {
							String coordinateNew = coordinate.replaceAll("_", ",");
							String[] numArray = coordinateNew.split(",");
							Cell cellNew = cellRelMap.get(numArray[1] + "--" + numArray[0]);
							String numKey = templateId + "--" + cellNew.getAbsColNum() + "--" + cellNew.getAbsRowNum();
							String cellValue = cellDataAbsMap.get(numKey);
							if (cellValue == null) {
								cellValue = "0";
							}
							try {
								cellFormual = cellFormual.replaceFirst(coordinate, cellValue);
							} catch (Exception e) {
								e.printStackTrace();
							}
						}
						try {
							String value = jse.eval(cellFormual).toString();
							BigDecimal valueBd = new BigDecimal(value);
							finalCellData = valueBd.intValue() + "";
						} catch (ScriptException e) {
							// TODO Auto-generated catch block
							finalCellData = "0";
						}
						CellData cellData = new CellData(cell, finalCellData, dzzId);
						calcCellDataListThread.add(cellData);
					}

				} catch (Exception e) {
					System.out.println(cell.getCellId() + "出错的CELLid--------------------------------");
					e.printStackTrace();
				}
			}

			return calcCellDataListThread;
		}
	}

	class ExecuteFuncThread implements Callable<List<CellData>> {
		private HttpSession session;
		RptTemplateUnitRela tu;
		private List<Cell> src;

		public ExecuteFuncThread(HttpSession session, List<Cell> src, RptTemplateUnitRela tu) {
			this.src = src;
			this.session = session;
			this.tu = tu;
		}

		@Override
		public List<CellData> call() {
			long start = System.nanoTime();
			List<CellData> cellDataList = executeFuncByTemplate(src, tu);
			long end = System.nanoTime();
			logger.error("ExecuteFuncThread : " + (end - start) / 1000000);
			start = end;
			AtomicInteger counter = (AtomicInteger) session.getAttribute("generationCounter");
			counter.addAndGet(cellDataList.size());
			session = null;
			return cellDataList;
		}

	}

}
